package yh.thread.threadstate;

/**
 * 线程的状态
 * @author: zyh
 * @date: 2024/10/10 19:26
 **/
public class ThreadState {


    /**
     * new
     */
    public static void  stateNew(){
        Thread thread =  new Thread(()->{
         System.out.println(Thread.currentThread().getName() + "正在执行....");
     });
        // 此时线程的状态是 new
        System.out.println("线程状态：" + thread.getState());
    }


    /**
     * runnable
     */
    public static  void stateRunnable() throws InterruptedException {
        Thread thread =  new Thread(()->{
            System.out.println(Thread.currentThread().getName() + "正在执行....");
        });
        System.out.println("线程new时刻状态：" + thread.getState());
        thread.start();
        //start() 后状态由 new -> runnable
        System.out.println("线程start后状态：" + thread.getState());

    }



   static Object object =  new Object();
    /**
     * Blocked
     */
    public static  void stateBlocked() throws InterruptedException {

        Thread thread1 =  new Thread(()->{
            synchronized (object){
                System.out.println(Thread.currentThread().getName() + "开始执行1....");
                try {
                // thread1 持有锁 10s
                Thread.sleep(10 * 1000);
                System.out.println(Thread.currentThread().getName() + "结束执行1....");
                } catch (InterruptedException e) {
                    throw new RuntimeException(e);
                }
            }
        });
        thread1.start();

        Thread thread2 =  new Thread(()->{
            synchronized (object){
                System.out.println(Thread.currentThread().getName() + "正在执行2....");
            }
        });
        System.out.println("线程new时刻状态：" + thread2.getState());
        thread2.start();
        System.out.println("线程start后状态：" + thread2.getState());
        Thread.sleep(5000);
        //thread2 需要竞争 object 锁，但是此刻object锁还没有释放，所以thread2的状态是 Blocked
        //这里需要添加 Thread.sleep(5000); 手动模拟延时5s，否则会直接打印 线程start后状态 Runnable
        System.out.println("线程此刻状态：" + thread2.getState());

    }


    /**
     * Waiting
     * @throws InterruptedException
     */
    public static void stateWaiting() throws Exception {
        Thread thread =  new Thread(()->{
            synchronized (object){
                try {
                    object.wait();
                    System.out.println(Thread.currentThread().getName() + "正在执行....");
                } catch (InterruptedException e) {
                    throw new RuntimeException(e);
                }
            }
        });
        thread.start();//此时 thread 线程状态 是 runnable
        //主线程睡眠3s 等待 thread 线程状态的变化
        Thread.sleep(3000);
        System.out.println("线程状态：" + thread.getState());
    }

    /**
     * TimedWaiting
     * @throws Exception
     */
    public static void stateTimedWaiting()throws Exception{
        Thread thread =  new Thread(()->{
            synchronized (object){
                try {
                    //等待4s 后执行
                    object.wait(4000);
                    System.out.println("线程状态：" + Thread.currentThread().getState());
                    //模拟业务代码执行
                    System.out.println(Thread.currentThread().getName() + "正在执行业务....");
                } catch (InterruptedException e) {
                    throw new RuntimeException(e);
                }
            }

        });
        thread.start(); //此时 【thread】线程状态 runnable
        System.out.println("线程启动时状态："  + thread.getState());
        //手动补一个延时 主线程睡眠2s后再监测线程状态 打印出变化量 从 runnable  ->  TimedWaiting
        Thread.sleep(2000);
        System.out.println("线程启动2s后【此刻】的状态：" + thread.getState());
    }


    /**
     * Terminated
     * @throws InterruptedException
     */
    public static void stateTerminated() throws InterruptedException {
      Thread thread =   new Thread(()->{
          System.out.println(Thread.currentThread().getName() + "执行1....");
        });
        thread.start();  // thread 状态是 Runnable
        //主线程睡 1s 【不加这一行代码 会打印 Runnable 看不到线程状态的变化】
        Thread.sleep(1000);
        //这个时候 thread 里面的方法已经执行完，[thread]线程由 Runnable -> Terminated
        Thread.State state = thread.getState();
        //主线程打印 thread 线程当前的状态
        System.out.println("线程状态："  + state);
    }







    public static void main(String[] args)throws Exception {
       // stateNew();
       // stateRunnable();
       // stateBlocked();
         //stateWaiting();
        stateTimedWaiting();
         //stateTerminated();
    }


}
